/**
 * 绘制多边形
 */
const { L } = window;
const calcPolygonArea = () => 0;

export default class Polygon {
  constructor(map, options) {
    Object.assign(this, {
      points: [],
      lines: L.polyline([]),
      tempLines: L.polyline([], { dashArray: 5 }),
      polygon: null,
      redPtArr: [],
      tooltip: null,
      cancelMarker: null,
      id: null,
      bShowTooltip: false,
      bStartDrag: false,
      bDragReady: true,
      areaName: null,
      needCancelBtn: false,
      needRedPt: false,
      needLocation: false,
      maxArea: null, // 限制最大的面积，不能超过它
      _area: 0,
      ...options,
    });
    this.init(map);
  }

  init(map) {
    this.parent = {};
    this.map = map;
  }

  startDraw({ callback, mouseMoveCallback }) {
    this.clear();
    this.id = "polygon_" + new Date().getTime();
    this.map.on("click", this.onClick); // 点击地图
    this.map.on("dblclick", this.onDoubleClick);
    this.map.on("mousemove", this.onMove); // 双击地图
    this.map.doubleClickZoom.disable(); // 禁用map双击事件
    this.callback = callback;
    this.mouseMoveCallback = mouseMoveCallback;
  }

  stop() {
    this.map.off("click", this.onClick); // 点击地图
    this.map.off("dblclick", this.onDoubleClick);
    this.map.off("mousemove", this.onMove); // 双击地图
  }

  clear() {
    this.stop();
    this.polygon && this.map.removeLayer(this.polygon);
    this.polygon = null;
    this.redPtArr.map((item) => this.map.removeLayer(item));
    this.redPtArr = [];
    this.tooltip && this.tooltip.remove();
    this.cancelMarker && this.map.removeLayer(this.cancelMarker);
    this.cancelMarker = null;

    this.map.removeLayer(this.tempLines);
    this.tempLines.remove();
    this.lines.remove();
    this.tempLines = L.polyline([], { dashArray: 5 });
    this.lines = L.polyline([]);
    this.points = [];
  }

  // map.off(....) 关闭该事件
  onClick = (e) => {
    L.DomEvent.stopPropagation(e); //阻止事件往map方向冒泡

    this.points.push([e.latlng.lat, e.latlng.lng]);
    this.lines.addLatLng(e.latlng);
    this.map.addLayer(this.tempLines);
    this.map.addLayer(this.lines);
    if (this.needRedPt) {
      const redPt = L.circle(e.latlng, 1, {
        color: "#ff0000",
        fillColor: "ff0000",
        fillOpacity: 1,
      });
      this.map.addLayer(redPt);
      this.redPtArr.push(redPt);
    }
  };

  onMove = (e) => {
    if (this.points.length > 0) {
      const ls = [
        this.points[this.points.length - 1],
        [e.latlng.lat, e.latlng.lng],
        this.points[0],
      ];
      let area = 0;
      let points = this.points
        .concat([[e.latlng.lat, e.latlng.lng]])
        .concat(this.points.slice(0, 1));
      if (points.length > 2) {
        points = L.polygon(points).getLatLngs()[0];
        area = calcPolygonArea(
          points.map((item) => {
            return item;
          })
        );
      }
      this._area = area;
      if (!this.maxArea || area < this.maxArea) {
        this.tempLines.setLatLngs(ls);
        if (this.mouseMoveCallback) {
          this.mouseMoveCallback({
            points: this.points,
            polygon: this.polygon,
            movingLatlng: e.latlng,
            area,
          });
        }
        this.polygon && this.map.removeLayer(this.polygon);
        let _color = "#32CEFF";
        let _fillOpacity = 0.6;
        this.polygon = new L.Polygon(this.points, {
          color: _color,
          fillColor: _color,
          fillOpacity: _fillOpacity,
          opacity: 0,
          weight: 2,
        }).addTo(this.map);
        // map.addLayer(tempLines)
      }
    }
  };

  onDoubleClick = (bSave = true) => {
    this.needCancelBtn &&
      this.addCancelBtn(new L.LatLng(...this.getCancelBtnPos()));
    const len = this.points.length;
    const lastPt = this.points[len - 1];
    const preLastPt = this.points[len - 2];
    if (lastPt.toString() === preLastPt.toString()) {
      this.points = this.points.slice(0, len - 1);
    }
    let _color, _fillOpacity;
    switch (this.areaMap) {
      case "coreArea":
        _color = "#73AEFF";
        _fillOpacity = 0.5;
        break;
      case "controlArea":
        _color = "#B652FF";
        _fillOpacity = 0.3;
        break;
      case "alertArea":
        _color = "#F60000";
        _fillOpacity = 0.4;
        break;
      default:
        _color = "#32CEFF";
        _fillOpacity = 0.6;
        break;
    }
    this.polygon && this.map.removeLayer(this.polygon);
    this.polygon = new L.Polygon(this.points, {
      maxMarkers: 100,
      color: _color,
      fillColor: _color,
      fillOpacity: _fillOpacity,
      opacity: 1,
      weight: 2,
      dragEndHander: () => this.onDragEnd(),
      setMapState: (flag) => this.setMapState(flag),
    }).addTo(this.map);
    // this.polygon = L.polygon(this.points, { color: "#2950B8", dashArray: 5 }).addTo(this.map);
    // this.polygon.on('click', () => {
    //   // this.tooltip.addTo(this.map);
    //   // this.setClickEvent(this.tooltip);
    // });
    this.select();
    this.pointsBak = [...this.points];
    // 清除辅助图形
    this.points = [];
    this.map.removeLayer(this.tempLines);
    this.tempLines.remove();
    this.lines.remove();
    this.tempLines.remove();
    this.lines = L.polyline([]);
    this.stop();
    this.map.doubleClickZoom.enable(); // 禁用map双击事件
    this.needLocation && this.map.fitBounds(this.polygon.getBounds());
    if (bSave) {
      this.parent.savePrevent &&
        this.parent.savePrevent(this.parent.currentEditPreventType, false);
    }
  };

  onDragEnd = () => {
    this.timer1 && clearTimeout(this.timer1);
    this.timer2 && clearTimeout(this.timer2);
    this.setTooltip();
    const points = [];
    this.polygon
      ._getMarkerLatLngs()
      .forEach((item) => points.push([item.lat, item.lng]));
    this.points = points;
    const latlng = this.getCancelBtnPos();
    this.cancelMarker.setLatLng(latlng);
    this.select();
    this.parent.savePrevent(this.parent.currentEditPreventType, false);
    this.timer1 = setTimeout(() => (this.bDragReady = true), 200);
    this.timer2 = setTimeout(() => this.setMapState(false), 500);
  };

  setClickEvent(tooltip) {
    const el = tooltip.getElement();
    el.addEventListener("click", (e) => L.DomEvent.stopPropagation(e));
    const bntSpan = el.getElementsByClassName("preventCircle-polygon-btn")[0];
    bntSpan.removeEventListener("click", this.savePrevent);
    bntSpan.addEventListener("click", this.savePrevent);
    el.style.pointerEvents = "auto";
  }

  select(isClear = false) {
    if (this.parent.doPolygonSelect)
      this.parent.doPolygonSelect({
        points: this.points,
        polygon: this.polygon,
        isClear,
      });
    if (this.callback) {
      this.callback({
        points: this.points,
        polygon: this.polygon,
        area: this._area,
      });
    }
  }
}
